module DengHaiLightTools
  # rubocop:disable Naming/MethodName

  # 自定义工具类
  module Tools
    # 放置灯具的工具
    class PutLight
      # 初始化，必须传递一个skp文件的路径
      def initialize(obj_path)
        @obj_path = obj_path
        check_DataManager
      end

      # 检查数据关联，以防用户手动清理缓存的组件定义。
      # 如果组件定义已经删除，就清理对应的键。
      # 目前还不清楚用户极端操作下会出现什么情况。
      def check_DataManager
        DengHaiLightTools::DataManager.data.each do |key, value|
          DengHaiLightTools::DataManager.data.delete(key) if value.is_a?(Sketchup::ComponentDefinition) && value.deleted?
        end
      end

      # 在激活插件时调用的方法
      def activate
        # 创建鼠标输入点对象
        @mouse_ip = Sketchup::InputPoint.new
        # 更新用户界面
        update_ui

        # 尝试加载或获取 skp 组件定义
        if (@skp_definition = load_or_get_skp_definition)
          # 处理 skp 组件定义
          handle_skp_definition
        else
          # 如果加载失败，选择取消当前工具
          Sketchup.active_model.select_tool(nil)
          return
        end
        @added_skp_instance = Sketchup.active_model.active_entities.add_instance(@skp_definition, Geom::Point3d.new(0, 0, 0))
        @added_skp_instance.visible = false
      end

      # 加载或获取 skp 组件定义
      def load_or_get_skp_definition
        # 如果已经存在于 DataManager 中，则直接返回
        return DengHaiLightTools::DataManager.get(@obj_path) if DengHaiLightTools::DataManager.get(@obj_path)

        # 否则，尝试加载 skp 文件
        skp_definition = DengHaiLightTools.load_skp_file(@obj_path)
        return nil unless skp_definition

        # 如果加载成功，将组件定义保存到 DataManager
        DengHaiLightTools::DataManager.set(@obj_path, skp_definition)
        skp_definition
      end

      # 处理 skp 组件定义
      def handle_skp_definition
        # 检查是否包含所需属性
        return if DengHaiLightTools.helpers_get_attribute(@skp_definition)

        # 如果不包含属性，显示错误消息
        UI.messagebox("灯具源文件不包含灯具属性。\n请检查文件是否已经损坏?")
        # 选择取消当前工具，并移除组件定义
        Sketchup.active_model.select_tool(nil)
        Sketchup.active_model.definitions.remove(@skp_definition)
      end

      def deactivate(view)
        @added_skp_instance.erase!
        view.invalidate
      end

      def resume(view)
        update_ui
        view.invalidate
      end

      def suspend(view)
        view.invalidate
      end

      def onCancel(_reason, view)
        view.invalidate
      end

      def draw(view)
        @mouse_ip.draw(view)
      end

      def onMouseMove(_flags, x, y, view)
        @mouse_ip.pick(view, x, y)
        # 这里我们让 SketchUp 显示其推断，类似于原生工具的方式。
        # view.tooltip = @mouse_ip.tooltip if @mouse_ip.valid?
        view.invalidate
      end

      # 当用户在视口中单击时，在PICK到的点上创建组件实例。
      def onLButtonDown(_flags, _x, _y, view)
        put_light_on_view
        update_ui
        view.invalidate
      end

      # 放置灯具，并且需为其添加自定义属性，这个属性也是标识他是否是合法灯具的标志
      def put_light_on_view
        return unless allow_placing_light?

        place_light
      end

      # 判断是否允许放置灯具
      # ==================================这里有bug，只有pick到灯具的时候才生效，否则不生效
      def allow_placing_light?
        nearest_entity = find_nearest_entity
        return true if nearest_entity.nil?

        result = UI.messagebox('重叠放置灯具？', MB_YESNO)
        result == IDYES
      end

      # 查找最近的实体
      def find_nearest_entity
        Sketchup.active_model.active_entities.find do |entity|
          entity.bounds.contains?(@mouse_ip.position) if DengHaiLightTools.helpers_get_attribute(entity)
        end
      end

      # 放置灯具
      def place_light
        Sketchup.active_model.start_operation('放置灯具')
        copyed_instance = @added_skp_instance.copy
        copyed_instance.visible = true
        copyed_instance.move!(@mouse_ip.position)
        lock_entities(copyed_instance.entities)
        copyed_instance.add_observer(DontEditIt.new)
        DengHaiLightTools.helpers_copy_attribute(@skp_definition, copyed_instance)
        Sketchup.active_model.commit_operation
      end

      # 锁定实体集合内的实体
      def lock_entities(entities)
        entities.each do |entity|
          entity.locked = true
        end
      end

      # `onSetCursor` 会频繁调用，因此在此处不应该做太多的工作。
      def onSetCursor
        UI.set_cursor(UI.create_cursor("#{ICON_PATH}/mouse_add_light.png", 0, 0))
      end

      def update_ui
        Sketchup.status_text = '鼠标左键放置灯具。按 Shift 根据当前点进行推断放置。'
      end
    end
  end
  # rubocop:enable Naming/MethodName
end
